var log=require("../utils/log");
var proto_tool=require("./protocol_tool");

var protocol = {
    PROTO_JSON: 1,  //json协议,字符串
    PROTO_BYTE: 2,  //二进制协议

    encode:encode,
    decode:decode,
    decode_head:decode_head,

    register_encoder:register_encoder,
    register_decoder:register_decoder,

    encrypt:encrypt,
    decrypt:decrypt
};

//编码表中保存所有的编码函数
var encoder_table={};

//解码表中保存所有的解码函数
var decoder_table={};


function get_key(stype,ctype){
	return stype*65536+ctype;
}

//加密
function encrypt(cmd){
	return cmd;
}

//解密
function decrypt(cmd){
	return cmd;
}


//编码
//协议类型,服务号,命令号,,用户标识,编码,二进制/字符串,body:[数据]
//编码的数据还没有加密
function encode(proto_type,stype,ctype,utag,body){

	var buf=Buffer.allocUnsafe(10);
	buf.writeUInt16BE(stype,0);
	buf.writeUInt16BE(ctype,2);
	buf.writeUInt32BE(utag,4);
	buf.writeUInt16BE(proto_type,8);

	if (body==null){
		return buf;
	}

    if (proto_type == protocol.PROTO_JSON) {
		
		//json对象转成字符串
		var json_str=JSON.stringify(body);
		//json字符串转成二进制流
    	var json_buf=null;
   		json_buf=proto_tool.add_str16(json_buf,json_str);

		return Buffer.concat([buf,json_buf]);
	}
	else{
		
		var key=get_key(stype,ctype);
		if (!encoder_table[key])
			return null;

		//字节流
		return Buffer.concat([buf,encoder_table[key](body)]);
	}

	return null;
}

//解码
//协议类型,二进制/字符串,body:[服务号,命令号,用户标识,编码,数据]
//body已经是解密后的数据
//body是"xxxxx"字符串
//body是"{name:xxx,age:yyy}"Json字符串
//body是二进制0001 0002 ...
function decode(proto_type,body){

	if (body.length<10)
		return null;

	var stype=body.readUInt16BE(0);
	var ctype=body.readUInt16BE(2);

	if (body.length==10){
		return null;
	}

    if (proto_type == protocol.PROTO_JSON) {

    	var json_len=body.readUInt16BE(10);
		return JSON.parse(body.toString("utf8",12,12+json_len));
	}
	else{
		
		var key=get_key(stype,ctype);
		if (!decoder_table[key])
			return null;

		return decoder_table[key](body.slice(10));
	}
	return null;
}


//解码头
//body已经是解密后的数据
function decode_head(body){
	var head={};

	if (body.length<10)
		return null;

	var stype=body.readUInt16BE(0);
	var ctype=body.readUInt16BE(2);
	var utag=body.readUInt32BE(4);
	var proto_type=body.readUInt16BE(8);

	head[0]=stype;
	head[1]=ctype;
	head[2]=utag;
	head[3]=proto_type;

	return head;
}

function register_encoder(stype,ctype,func){
	var key=get_key(stype,ctype);
	if (encoder_table[key])
		log.warn("stype:"+stype+" ctype:"+ctype+"已经注册了");

	encoder_table[key]=func;
}

function register_decoder(stype,ctype,func){
	var key=get_key(stype,ctype);
	if (decoder_table[key])
		log.warn("stype:"+stype+" ctype:"+ctype+"已经注册了");

	decoder_table[key]=func;
}


module.exports=protocol;